<template>
  <basic-container>
    <avue-crud
      :option="option"
      :table-loading="loading"
      :data="data"
      v-model="form"
      :page.sync="page"
      :permission="permissionList"
      :before-open="beforeOpen"
      :before-close="beforeClose"
      ref="crud"
      @row-update="rowUpdate"
      @row-save="rowSave"
      @row-del="rowDel"
      @search-change="searchChange"
      @search-reset="searchReset"
      @selection-change="selectionChange"
      @current-change="currentChange"
      @size-change="sizeChange"
      @refresh-change="refreshChange"
      @on-load="onLoad"
      :defaults.sync="defaults"
    >
      <template slot="menuLeft">
        <el-button type="danger" size="small" icon="el-icon-delete" v-if="permission.sequencedefinition_delete" @click="handleDelete">删 除 </el-button>
      </template>
      <template slot-scope="{ row }" slot="menu">
        <el-button icon="el-icon-delete" size="small" type="text" v-if="permission.sequencedefinition_delete" :disabled="row.isForSystem" @click="$refs.crud.rowDel(row)"
          >删除</el-button
        >
      </template>
      <!--      <template slot="menuRight">-->
      <!--        <user-table-config :option="option" @confirm="(val) => handleSetUserConfig(val, pageCode)"></user-table-config>-->
      <!--      </template>-->
      <template slot="sequenceSampleForm">
        <div>[PN][VDC][PQ][YY][S] 料品编码+供应商(客户)代码+包装数量+两位年份+流水</div>
      </template>
      <template slot="baseInfoForm">
        <div class="title">
          <i class="el-icon-vertical-bar avue-group__icon"></i>
          <h4>基础信息</h4>
        </div>
      </template>
      <template slot="rulesCofigForm">
        <div class="title">
          <i class="el-icon-vertical-bar avue-group__icon"></i>
          <h4>规则配置</h4>
        </div>
      </template>
      <template slot="sequencenoformatForm">
        <div>
          <el-input v-model="form.sequencenoformat" placeholder="序列号规则" readonly :disabled="inputDisabled" @focus.native.capture="sequenceNoKeyUp"></el-input>
          <div id="sequenceDropdown" class="sequence-dropdown" :class="{ show: isCollapsed }">
            <div class="closeDropDown"><i class="el-icon-circle-close" @click="closeDropDown" /></div>
            <div class="seqNoRulesList">
              <div v-for="(item, eleIndex) in seqNoRulesList" :key="item.code">
                <p class="form-title">{{ item.name }}</p>
                <div class="checkbox">
                  <div class="grid-content bg-purple">
                    <el-row :class="item.code">
                      <div v-for="(childItem, index) in item.value" :key="childItem.key">
                        <el-col span="8" v-if="item.code !== 'customCode'">
                          <!--下面一行为占位div-->
                          <div v-if="eleIndex === 0 && index === 11" style="width: 50px">&nbsp;</div>
                          <!-- <div v-else-if="eleIndex === 1 && index === 26" style="width: 50px">&nbsp;</div> -->
                          <el-checkbox
                            v-else
                            class="custom-check-box"
                            v-model="selectedRuleCodes[childItem.key]"
                            :indeterminate="indeterminate"
                            :name="childItem.key"
                            :value="childItem.key"
                            @change="checkboxOnClick(childItem)"
                            >{{ childItem.value }}
                          </el-checkbox>
                        </el-col>
                        <el-col span="17" v-else>
                          <div class="custom-char">
                            <el-checkbox
                              class="custom-check-box"
                              v-model="selectedRuleCodes[childItem.key]"
                              :indeterminate="indeterminate"
                              :name="childItem.key"
                              :value="childItem.key"
                              @change="checkboxOnClick(childItem)"
                              >{{ childItem.value }}
                            </el-checkbox>
                            <el-popover
                              placement="top"
                              width="300"
                              trigger="click"
                              @show="handleEditCustomField(childItem, index)"
                              @hide="handleSetCustomField(childItem, index)"
                            >
                              <div class="custom-form">
                                <avue-form :option="customOption" v-model="customForm"> </avue-form>
                              </div>
                              <el-button type="text" size="small" icon="el-icon-edit" slot="reference" :disabled="selectedRuleCodes[childItem.key]">编辑 </el-button>
                            </el-popover>
                            <el-button
                              type="text"
                              size="small"
                              class="btn-del"
                              icon="el-icon-delete"
                              :disabled="selectedRuleCodes[childItem.key]"
                              @click.stop="handleDeleteField(childItem, index)"
                              >删 除
                            </el-button>
                          </div>
                        </el-col>
                      </div>
                    </el-row>
                  </div>
                </div>
                <el-button
                  type="text"
                  @click="addCustomCode"
                  icon="el-icon-circle-plus-outline"
                  size="small"
                  style="border: 0; background-color: transparent !important"
                  v-if="item.code === 'customCode'"
                  >添加字符
                </el-button>
              </div>
            </div>
          </div>
        </div>
      </template>
      <template slot="previewForm">
        <el-input v-model="preview" :disabled="true"></el-input>
      </template>
      <!-- <template slot="customCodeForm">
        <span>{{ seqNoRulesList[2].value.length }}</span>
        <div v-for="(item, index) in seqNoRulesList[2].value || []" :key="index">
          <label class="el-form-item__label">自定义字符1</label>
          <el-input
            v-model="item.value"
          ></el-input>
        </div>
      </template> -->
      <!-- <template slot-scope="{row}"
                      slot="containsSequenceNo">
                <el-tag>{{ row.containsSequenceNo === 0 ? '否' : '是' }}</el-tag>
            </template> -->
      <template slot-scope="{ row }" slot="isIdentifyAlso">
        <el-tag>{{ row.isIdentifyAlso === false ? '否' : '是' }}</el-tag>
      </template>
      <!--      <template slot-scope="{ row }" slot="requirePlaceholderReplacement">-->
      <!--        <el-tag>{{ row.requirePlaceholderReplacement === false ? '否' : '是' }}</el-tag>-->
      <!--      </template>-->
    </avue-crud>
  </basic-container>
</template>

<script>
import { getList, getDetail, add, addOrUpdate, remove } from '@/api/admin/sequencedefinition';
import { getSeqNoRules, getKeyValueMap } from '@/util/global';
import { mapGetters } from 'vuex';
import userTableConfig from '@/components/user-table-config';
import userConfig from '@/mixins/userConfig';
export default {
  name: 'AdminSequencedefinition',
  components: {
    userTableConfig
  },
  mixins: [userConfig()],
  data() {
    var validateSequencenoformat = (rule, value, callback) => {
      if (value === '') {
        callback(new Error('请选择序列号规则'));
      } else if (this.form.type === 'MATERIAL' && value.indexOf('[S]') === -1 && value.indexOf('[CN]') === -1) {
        callback(new Error('请选择流水[S]规则或者[CN]箱号规则'));
      } else if (
        value.indexOf('[SN]') === -1 &&
        value.indexOf('[S]') === -1 &&
        this.form.type !== 'CODE' &&
        this.form.type !== 'LOTNO' &&
        this.form.type !== 'EQUIPMENT' &&
        this.form.type !== 'STATION' &&
        this.form.type !== 'MATERIAL'
      ) {
        callback(new Error('未选择流水[S]规则'));
      } else if (
        value.indexOf('[SN]') === -1 &&
        value.indexOf('[S]') != -1 &&
        (this.form.type === 'CODE' || this.form.type === 'LOTNO' || this.form.type === 'EQUIPMENT' || this.form.type === 'STATION')
      ) {
        callback(new Error('当前条码类型不能存在流水[S]规则'));
      } else if (value.indexOf('[SN]') === -1 && this.form.type === 'OUTSN' && value.indexOf('[PN]') === -1) {
        callback(new Error('未选择料品编码[PN]规则'));
      } else {
        callback();
      }
    };

    var validateHexString = (rule, value, callback) => {
      // 辅助函数
      function isRepeat(str) {
        const hash = new Map();
        for (let i = 0; i < str.length; i++) {
          const c = str[i];
          if (hash.has(c)) {
            return true;
          } else {
            hash.set(c, true);
          }
        }
        return false;
      }
      const regexStr = /^[0-9a-zA-Z]+$/;
      // 校验: 1 空值  2 重复  3进制字符是否0-9a-zA-z 4
      // 4 34进制是 0~9+A~Z 字母不含I O , length = 34
      // 5 32进制是 0~9+A~Z 字母不含I O S Z， length = 32
      if (value === '') {
        callback(new Error('请输入进制字符'));
      }

      // let isRepeat = false;
      // out: for (let i = 0; i < value.length; i++) {
      //     for (let j = i + 1; j < value.length; j++) {
      //         if (value[i] === value[j]) {
      //             isRepeat = true;
      //             break out;
      //         } else {
      //             isRepeat = false;
      //         }
      //     }
      // }
      // 重复校验
      if (isRepeat(value)) {
        callback(new Error('进制字符中不能存在重复的字符'));
      }
      if (!regexStr.test(value)) {
        callback(new Error('进制字符中只能包含0-9和字母'));
      }
      if (value.length === 34 && ['I', 'O'].some((item) => value.includes(item))) {
        callback(new Error('34进制字符中不能包含I O 字符'));
      }
      if (value.length === 32 && ['I', 'O', 'S', 'Z'].some((item) => value.includes(item))) {
        callback(new Error('32进制字符中不能包含I O S Z字符'));
      }
      callback();
      // else {
      //   if (isRepeat) {
      //   } else {
      //     let str = /^[0-1a-zA-Z]+$/;
      //     if (!str.test(value)) {
      //       callback(new Error('进制字符中只能包含0-9和字母'));
      //     } else {
      //       callback();
      //     }
      //
      //     // 34进制是 0~9+A~Z 字母不含I O , length = 34
      //     // 32进制是 0~9+A~Z 字母不含I O S Z， length = 32
      //   }
      // }
    };
    return {
      pageCode: 'ADMIN_SEQUENCEDEFINITION',
      form: {},
      query: {},
      loading: true,
      page: {
        pageSize: 20,
        currentPage: 1,
        total: 0
      },
      preViewMap: getKeyValueMap(),
      inputDisabled: false,
      customizedPlaceholder: [],
      selectionList: [],
      columns: [],
      seqNoRulesList: getSeqNoRules(),
      isCollapsed: false,
      indeterminate: false, //属性 不确定形式
      selectedRuleCodes: {},
      customForm: {},
      customOption: {
        emptyBtn: false,
        submitBtn: false,
        column: [
          {
            label: '字符名称',
            prop: 'label',
            span: 24,
            rules: [
              {
                required: false,
                trigger: 'change',
                validator: (rule, value, callback) => {
                  const seqNoRulesValue = this.seqNoRulesList[2].value.map((item) => item.value);
                  seqNoRulesValue.splice(this.currentIndex, 1);
                  if (seqNoRulesValue.includes(value)) {
                    callback(new Error('该字符名称已存在，请重新输入！'));
                    this.isSubmit = false;
                  } else {
                    this.isSubmit = true;
                  }
                }
              }
            ]
          },
          {
            label: '字符代码',
            prop: 'code',
            span: 24,
            rules: [
              {
                required: false,
                trigger: 'change',
                validator: (rule, value, callback) => {
                  if (!(value.indexOf('[') === 0) || !(value.indexOf(']') === value.length - 1) || value.length < 3) {
                    callback(new Error('该字符代码需要为[X]格式，请重新输入'));
                    this.isSubmit = false;
                    return;
                  } else {
                    const seqNoRulesKey = this._cloneDeep(this.seqNoRulesKey);
                    if (seqNoRulesKey.includes(value) && value !== this.currentKey) {
                      callback(new Error('该字符代码已存在，请重新输入'));
                      this.isSubmit = false;
                      return;
                    }
                  }
                  this.isSubmit = true;
                }
              }
            ]
          },
          {
            label: '字符值',
            prop: 'value',
            span: 24
          }
        ]
      },
      option: {
        height: 'calc(100vh - 440px)',
        dialogCustomClass: 'custom-dialog',
        calcHeight: 30,
        tip: false,
        searchShow: true,
        searchMenuSpan: 6,
        border: true,
        index: true,
        // inline: true,
        viewBtn: true,
        delBtn: false,
        viewBtnText: '详情',
        viewTitle: '详情',
        selection: true,
        menuWidth: 200, //弹框内字段宽度属性
        dialogWidth: 880, //弹框宽度属性
        labelWidth: '160',
        dialogClickModal: false,
        indexLabel: '序号',
        columnBtn: false,
        column: [
          {
            prop: 'baseInfo',
            formslot: true, // 定义form表单中字段的插槽
            hide: true,
            row: true,
            span: 24
          },
          {
            label: '类型',
            prop: 'type',
            search: true,
            type: 'select',
            dicUrl: '/api/blade-system/dict/dictionary?code=serial_number_rule_type',
            props: {
              label: 'dictValue',
              value: 'dictKey'
            },
            change: ({ column, value }) => {
              if (['view', 'edit'].includes(column.boxType)) {
                this.$set(this.form, 'sequencenoformat', this.form.sequenceNoFormat);
                return;
              }
              if (value === 'LOTNO') {
                this.form.name = '原材料批次规则';
                this.form.sequencenoformat = '[VD]';
                this._forEach(this.seqNoRulesList, (item) => {
                  this._forEach(item.value, (itemValue) => {
                    if (itemValue.key === '[VD]') {
                      this.selectedRuleCodes[itemValue.key] = true;
                    } else {
                      this.selectedRuleCodes[itemValue.key] = false;
                    }
                  });
                });
              } else {
                this.form.name = '';
                this.form.sequencenoformat = '';
                this._forEach(this.seqNoRulesList, (item) => {
                  this._forEach(item.value, (itemValue) => {
                    this.selectedRuleCodes[itemValue.key] = false;
                  });
                });
              }
            },
            blur: ({ column, value }) => {
              this.form = {
                type: value
              };
            },
            rules: [
              {
                required: true,
                message: '请输入序列号规则类型',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '名称',
            prop: 'name',
            search: true,
            value: '',
            rules: [
              {
                required: true,
                message: '请输入序列号规则名称',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '编码',
            prop: 'code',
            search: true,
            rules: [
              {
                required: true,
                message: '请输入序列号规则编码',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '预生成序列号',
            prop: 'isPregenerated',
            type: 'switch', //开关的类型
            align: 'center',
            hide: true,
            dicData: [
              {
                label: '否',
                value: false
              },
              {
                label: '是',
                value: true
              }
            ],
            value: false
          },
          {
            label: '已使用序列号数量',
            prop: 'used',
            hide: true,
            display: false,
            disabled: true
          },
          {
            label: '序列号总数量',
            prop: 'total',
            hide: true,
            display: false,
            disabled: true
          },
          {
            label: '进制类型',
            prop: 'baseType',
            type: 'radio',
            hide: true,
            labelTip:
              '序列号生成流水的进制，十进制为10进1，十六进制为16进1；如进制类型为十进制，</br> 则进制字符为0123456789；如进制类型为十六进制， 则进制字符为0123456789ABCDEF',
            value: 10,
            dicData: [
              {
                label: '十进制',
                value: 10
              },
              {
                label: '十六进制',
                value: 16
              },
              {
                label: '自定义',
                value: 'custom'
              }
            ],
            disabled: false,
            control: (val, form) => {
              if (val === 10 && form['isPregenerated'] !== true) {
                return {
                  hexString: {
                    disabled: true
                  },
                  serialNumberTotal: {
                    display: form['type'] !== 'OUTSN'
                  }
                };
              } else if (val === 16) {
                return {
                  hexString: {
                    disabled: true
                  },
                  serialNumberTotal: {
                    display: form['type'] !== 'OUTSN'
                  }
                };
              } else {
                return {
                  hexString: {
                    disabled: false,
                    value: ''
                  },
                  serialNumberTotal: {
                    display: false
                  }
                };
              }
            },
            change: (val) => {
              if (val.value === 10) {
                this.form.hexString = '0123456789';
              } else if (val.value === 16) {
                this.form.hexString = '0123456789ABCDEF';
              } else {
                this.form.hexString = this.customHexString;
              }
            }
          },
          {
            label: '进制字符',
            prop: 'hexString',
            hide: true,
            disabled: true,
            rules: [{ required: true, validator: validateHexString, trigger: 'blur' }]
          },
          {
            label: '起始流水号',
            prop: 'startSequenceNo',
            value: '00001',
            // hide: true,
            rules: [
              {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                  let reg;
                  let strIndex = 0;
                  if (this.form.baseType === 10) {
                    reg = /^[0-9]\d*$/g;
                  } else if (this.form.baseType === 16) {
                    reg = /^[A-F0-9]+$/;
                  } else {
                    for (let i = 0; i < value.length; i++) {
                      if (this.form.hexString.indexOf(value[i]) == -1) {
                        strIndex = -1;
                        break;
                      }
                    }
                  }
                  if (this.form.baseType === 'custom' && strIndex == -1) {
                    callback(new Error('起始流水号不符合进制字符！'));
                  } else if (this.form.baseType != 'custom' && value && !reg.test(value)) {
                    callback(new Error('起始流水号不符合进制字符！'));
                  } else {
                    if (!value) {
                      callback(new Error('起始流水号不能为空！'));
                    } else {
                      if (this.form.baseType === 16 && value.length > 15) {
                        callback(new Error('起始流水号最多只能有15位！'));
                      } else if (this.form.baseType === 10 && value.length > 9) {
                        callback(new Error('起始流水号最多只能有9位！'));
                      } else if (this.form.baseType === 'custom' && value.length > this.form.hexString.length) {
                        callback(new Error(`起始流水号最多只能有${this.form.hexString.length}位！`));
                      } else {
                        if (this.form.endSequenceNo) {
                          let start = value.replace(/\b(0+)/gi, '');
                          let end = this.form.endSequenceNo.replace(/\b(0+)/gi, '');
                          if (start != '') {
                            if (start.length > end.length) {
                              callback(new Error('起始流水号不能大于结束流水号！'));
                            } else {
                              let k = 0;
                              let n = 0;
                              while (k <= start.length - 1) {
                                let startIndex = this.form.hexString.indexOf(start[k]);
                                let endIndex = this.form.hexString.indexOf(end[k]);
                                if (startIndex <= endIndex) {
                                  n++;
                                } else if (startIndex > endIndex && start.length >= end.length) {
                                  callback(new Error('起始流水号不能大于结束流水号！'));
                                  return;
                                } else if (startIndex > endIndex && start.length < end.length) {
                                  n++;
                                }
                                k++;
                              }
                              if (n > 0) {
                                callback();
                              }
                            }
                          } else {
                            callback();
                          }
                        }
                      }
                    }
                  }
                }
              }
            ],
            change: (val) => {
              setTimeout(() => {
                if (this.form.baseType === 16) {
                  let startNum = parseInt(val.value, 16);
                  let endNum = parseInt(this.form.endSequenceNo, 16);
                  this.form.serialNumberTotal = endNum - startNum + 1;
                } else if (this.form.baseType === 10) {
                  this.form.serialNumberTotal = Number(this.form.endSequenceNo) - Number(val.value) + 1;
                }
                // } else {
                //   let startNum = parseInt(val.value, this.form.hexString.length);
                //   let endNum = parseInt(this.form.endSequenceNo, this.form.hexString.length);
                //   this.form.serialNumberTotal = Number(endNum - startNum) + 1;
                // }
              }, 500);
            }
          },
          {
            label: '结束流水号',
            prop: 'endSequenceNo',
            value: '99999',
            // hide: true,
            rules: [
              {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                  let reg;
                  let strIndex = 0;
                  if (this.form.baseType === 10) {
                    reg = /^[0-9]\d*$/g;
                  } else if (this.form.baseType === 16) {
                    reg = /^[A-F0-9]+$/;
                  } else {
                    for (let i = 0; i < value.length; i++) {
                      if (this.form.hexString.indexOf(value[i]) == -1) {
                        strIndex = -1;
                        break;
                      }
                    }
                  }
                  if (this.form.baseType === 'custom' && strIndex == -1) {
                    callback(new Error('结束流水号不符合进制字符！'));
                  }
                  if (this.form.baseType != 'custom' && value && !reg.test(value)) {
                    callback(new Error('结束流水号不符合进制字符！'));
                  } else {
                    if (!value) {
                      callback(new Error('结束流水号不能为空！'));
                    } else {
                      if (this.form.baseType === 16 && value.length > 15) {
                        callback(new Error('结束流水号最多只能有15位！'));
                      } else if (this.form.baseType === 10 && value.length > 9) {
                        callback(new Error('结束流水号最多只能有9位！'));
                      } else if (this.form.baseType === 'custom' && value.length > this.form.hexString.length) {
                        callback(new Error(`结束流水号最多只能有${this.form.hexString.length}位！`));
                      } else {
                        if (this.form.startSequenceNo) {
                          let start = this.form.startSequenceNo.replace(/\b(0+)/gi, '');
                          let end = value.replace(/\b(0+)/gi, '');
                          if ((start != '' && end === '') || (start != '' && end != '')) {
                            if (start.length > end.length) {
                              callback(new Error('起始流水号不能大于结束流水号！'));
                            } else {
                              let k = 0;
                              let n = 0;
                              while (k <= start.length - 1) {
                                let startIndex = this.form.hexString.indexOf(start[k]);
                                let endIndex = this.form.hexString.indexOf(end[k]);
                                if (startIndex <= endIndex) {
                                  n++;
                                } else if (startIndex > endIndex && start.length >= end.length) {
                                  callback(new Error('起始流水号不能大于结束流水号！'));
                                  return;
                                } else if (startIndex > endIndex && start.length < end.length) {
                                  n++;
                                }
                                k++;
                              }
                              if (n > 0) {
                                callback();
                              }
                            }
                          } else {
                            callback();
                          }
                        }
                      }
                    }
                  }
                }
              }
            ],
            change: (val) => {
              setTimeout(() => {
                if (this.form.baseType === 16) {
                  let startNum = parseInt(this.form.startSequenceNo, 16);
                  let endNum = parseInt(val.value, 16);
                  this.form.serialNumberTotal = endNum - startNum + 1;
                } else if (this.form.baseType === 10) {
                  this.form.serialNumberTotal = Number(val.value) - Number(this.form.startSequenceNo) + 1;
                }
                // } else {
                //   let startNum = parseInt(this.form.startSequenceNo, this.form.hexString.length);
                //   let endNum = parseInt(val.value, this.form.hexString.length);
                //   this.form.serialNumberTotal = Number(endNum - startNum) + 1;
                // }
              }, 500);
            }
          },
          {
            label: '产品序列号总数',
            prop: 'serialNumberTotal',
            hide: true,
            disabled: true
          },
          {
            label: '清零类型',
            prop: 'regressionType',
            type: 'select',
            value: 'Year',
            dicData: [
              {
                label: '不清零',
                value: 'Never'
              },
              {
                label: '年',
                value: 'Year'
              },
              {
                label: '月',
                value: 'Month'
              },
              {
                label: '周',
                value: 'Week'
              },
              {
                label: '日',
                value: 'Day'
              }
            ],
            rules: [
              {
                required: true,
                trigger: 'blur',
                validator: (rule, value, callback) => {
                  callback();
                }
              }
            ]
          },
          {
            label: '增量',
            prop: 'incrementQty',
            type: 'number',
            hide: true,
            precision: 0,
            minRows: 1,
            rules: [
              {
                required: false,
                message: '请输入增量',
                trigger: 'blur'
              }
            ]
          },

          {
            prop: 'rulesCofig',
            formslot: true, // 定义form表单中字段的插槽
            hide: true,
            row: true,
            span: 24
          },
          {
            label: '条码样例',
            // 当前规则生成的一个样例序列号
            prop: 'sequenceSample',
            hide: true,
            display: true,
            value: '[PN][VDC][PQ][YY][S] 料品编码+供应商(客户)代码+包装数量+两位年份+流水',
            disabled: true,
            span: 24,
            formslot: true, // 定义form表单中字段的插槽
            row: true
          },
          {
            label: '前缀字符',
            prop: 'prefix',
            hide: true,
            labelTip: '生成流水的前缀',
            rules: [
              {
                required: false,
                message: '请输入前缀字符',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '后缀字符',
            prop: 'suffix',
            hide: true,
            labelTip: '生成流水的后缀',
            rules: [
              {
                required: false,
                message: '请输入后缀字符',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '条码规则',
            prop: 'sequencenoformat',
            width: 200,
            formslot: true, // 定义form表单中字段的插槽
            labelTip:
              '[P]：前缀字符,[YY]：两位年份, [YYYY]：四位年份, [M]：月,<br />[W]：周, [D]：日,[S]：流水号, [N]：自定义字符。<br />[B]：后缀字符 <br />如：[YY][M][S][B]<br />若无流水号则没有[S],例如：[YY][M][B]',
            rules: [
              {
                required: true,
                validator: validateSequencenoformat,
                trigger: 'submit'
              }
            ]
          },
          {
            label: '条码规则预览',
            prop: 'preview',
            width: 200,
            formslot: true // 定义form表单中字段的插槽
          },
          // {
          //   label: '清零过滤字符',
          //   prop: 'filterChar',
          //   type: 'select',
          //   multiple: true,
          //   hide: true,
          //   width: 200,
          //   dicData: []
          // },
          {
            label: '规则位数',
            prop: 'charactersCount',
            type: 'number',
            precision: 0,
            minRows: 1,
            hide: true,
            rules: [
              {
                required: false,
                message: '请输入序列号规则位数',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '分组规则',
            prop: 'groupingRule',
            hide: true,
            rules: [
              {
                required: false,
                message: '请输入分组规则',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '分隔符',
            // 每个占位符之间的分隔符，用于识别外来编码每个部分的值，比如‘；’，‘/’等，如果需要用于识别条码，必须要配置分隔符。
            prop: 'delimiter',
            type: 'select',
            dicUrl: '/api/blade-system/dict/dictionary?code=delimiter_type',
            hide: true,
            props: {
              label: 'dictValue',
              value: 'dictKey'
            }
          },
          {
            label: '识别码',
            prop: 'identificationCode',
            hide: true,
            labelTip: '当有多个识别码时，格式为xxx,xxx，即用逗号隔开'
          }
        ]
      },
      data: [],
      defaults: {},
      customHexString: ''
    };
  },
  watch: {
    'form.type'(val) {
      this.isFieldShow(val);
    },
    'form.isPregenerated'(val) {
      const used = this.findObject(this.option.column, 'used');
      const total = this.findObject(this.option.column, 'total');
      if (val) {
        const isShowOtherField = (item) => ['type', 'name', 'used', 'total', 'isPregenerated', 'code'].includes(item.prop);
        used.display = true;
        total.display = true;
        this._forEach(this.option.column, (item) => {
          if (!isShowOtherField(item)) {
            item.display = false;
          }
          switch (item.prop) {
            case 'type':
              item.disabled = false;
              break;
            case 'name':
              item.disabled = false;
              break;
            case 'code':
              item.disabled = false;
              break;
            case 'isPregenerated':
              item.disabled = false;
              break;
            default:
              item.disabled = true;
              break;
          }
        });
      } else {
        used.display = false;
        total.display = false;
        const isShowOtherField = (item) => ['used', 'total'].includes(item.prop);
        this._forEach(this.option.column, (item) => {
          if (!isShowOtherField(item) && this.form.type !== 'OUTSN') {
            item.display = true;
          }
          switch (item.prop) {
            case 'used':
              item.disabled = true;
              break;
            case 'total':
              item.disabled = true;
              break;
            case 'hexString':
              item.disabled = true;
              break;
            case 'serialNumberTotal':
              item.disabled = true;
              break;
            default:
              item.disabled = false;
              break;
          }
        });
        this.isFieldShow(this.form.type);
      }
    }
    // 'form.sequencenoformat'(val) {
    //   let result;
    //   try {
    //     const array = val.split('[').filter((item) => item !== '') || [];
    //     //因为上面出除去了[ 下面补[ 即可
    //     result = array.map((item) => ({ label: `[${item}`, value: `[${item}` }));
    //     if (!array.length) {
    //       this.form.filterChar = [];
    //     }
    //   } catch (e) {
    //     result = [];
    //   }
    //   const column = this.findObject(this.option.column, 'filterChar');
    //   column.dicData = result;
    // }
  },
  computed: {
    ...mapGetters(['permission']),
    permissionList() {
      return {
        addBtn: this.vaildData(this.permission.sequencedefinition_add, false),
        viewBtn: this.vaildData(this.permission.sequencedefinition_view, false),
        delBtn: this.vaildData(this.permission.sequencedefinition_delete, false),
        editBtn: this.vaildData(this.permission.sequencedefinition_edit, false)
      };
    },
    ids() {
      let ids = [];
      this.selectionList.forEach((ele) => {
        ids.push(ele.id);
      });
      return ids.join(',');
    },
    preview() {
      let str = '';
      const sequencenoformat = this.form.sequencenoformat || '';
      if (!sequencenoformat) {
        return '';
      }
      const array = sequencenoformat.split('[').filter((item) => item !== '') || [];
      const sequencenoformatArr = array.map((item) => `[${item}`);
      sequencenoformatArr.forEach((item) => {
        str += this.preViewMap[item] || '';
      });
      return str;
    }
  },
  mounted() {
    this.$nextTick(() => {
      //搜索与表格结构分隔
      this.$structuralSplit();
    });
  },
  methods: {
    /**
     * 序列号规则输入框点击触发事件
     */
    sequenceNoKeyUp() {
      if (!this.form.type) {
        this.$message({
          type: 'warning',
          message: '请先选择类型!'
        });
        return;
      }
      this.isCollapsed = this.isCollapsed === false;
      this.checkBoxControl();
    },
    closeDropDown() {
      this.isCollapsed = false;
      this.checkBoxControl();
    },
    checkBoxControl() {
      if (this.form.sequencenoformat) {
        const seqNoFormatZh = this.form.sequencenoformat;
        var splitList = seqNoFormatZh.split('');
        // 在[前加空格  ]后加空格
        splitList = splitList.map((item) => {
          if (item === '[') {
            return ' [';
          } else if (item === ']') {
            return '] ';
          } else {
            return item;
          }
        });
        splitList = splitList.join('');
        // 按空格拆分字符串
        splitList = splitList.split(' ');
        splitList.forEach((ele) => {
          if (ele !== '') {
            this.selectedRuleCodes[ele] = true;
          }
          if (ele === '') {
            this.selectedRuleCodes[ele] = null;
          }
        });
      }
    },
    /**
     * 序列号规则复选框点击事件
     */
    checkboxOnClick(childItem) {
      if (this.form.sequencenoformat) {
        // 若当前选中的复选框已经存在于输入框中则移除，反之添加
        if (this.form.sequencenoformat.indexOf(childItem.key) !== -1) {
          try {
            // 原来的逻辑
            let reg = /^\[(N\d+)\]$/; //正则匹配[N1] => N1
            let res = childItem.key.match(reg);
            this.form.sequencenoformat = this.form.sequencenoformat.replace(childItem.key, '');
            this.option.column = this._differenceWith(this.option.column, [res[1]], (item, item2) => {
              return item.prop === item2;
            });
          } catch (e) {
            console.log(e);
          } finally {
            //删除去除勾选的过滤字符
            /// this.form.filterChar = this.form.filterChar.filter((item) => !item.includes(childItem.key));
            // this.customizedPlaceholderFn(childItem);
          }
        } else {
          if (childItem.key === '[P]') {
            this.form.sequencenoformat = '[P]' + this.form.sequencenoformat;
          } else if (childItem.key === '[B]') {
            this.form.sequencenoformat = this.form.sequencenoformat + '[B]';
          } else if (this.form.sequencenoformat.includes('[B]')) {
            this.form.sequencenoformat = this.form.sequencenoformat.replace('[B]', '');
            this.form.sequencenoformat = this.form.sequencenoformat + childItem.key + '[B]';
          } else {
            this.form.sequencenoformat += childItem.key;
          }
          // this.addCustomInput(childItem);
        }
      } else {
        //   this.addCustomInput(childItem);
        this.form.sequencenoformat = childItem.key;
      }
    },
    /*
     * 当选择自定自定checkbox时，添加相应的自定义字符输入框
     */
    addCustomInput(childItem) {
      if (this.form.type === 'CODE') {
        let reg = /^\[(N\d+)\]$/; //正则匹配[N1] => N1
        let res = childItem.key.match(reg);
        if (!res) {
          return;
        }
        this.option.column = [
          ...this.option.column,
          {
            label: `${childItem.value}`,
            prop: `${res[1]}`,
            hide: true,
            isCustomChart: true,
            rules: [
              {
                required: true,
                message: `请输入${childItem.value}`,
                trigger: 'blur'
              }
            ]
          }
        ];
        // this.customizedPlaceholderFn(childItem)
      }
    },
    customizedPlaceholderFn() {
      let reg = /^\[(N\d+)\]$/; //正则匹配[N1] => N1
      let arr = [];
      this._forEach(this.seqNoRulesList[2].value, (item) => {
        let res = item.key.match(reg);
        arr.push({
          code: res[1],
          label: item.value,
          dataType: 'String'
        });
      });
      this.customizedPlaceholder = arr;
    },
    rowSave(form, done, loading) {
      form['sequenceNoFormat'] = this.form.sequencenoformat;
      let arr;
      if (this.form.type === 'CODE') {
        const value = this.seqNoRulesList[2].value || [];
        let tempArr = [];
        value.forEach((item) => {
          if (this.form.sequencenoformat.includes(item.key)) {
            tempArr.push({ code: item.key, label: item.label || item.value, dataType: 'String', value: item.code });
          }
          // return {
          //   // ...item,
          //   // label: this.form[item.code] || '',
          //   // dataType: 'String',
          //   // value: this.form[item.code]
          //   code: item.key,
          //   label: item.label,
          //   dataType: 'String',
          //   value: item.code
          // };
        });
        arr = JSON.stringify(tempArr);
      } else {
        const value = this.seqNoRulesList[2].value || [];
        console.log(value);
        let tempArr = [];
        value.forEach((item) => {
          if (this.form.sequencenoformat.includes(item.key)) {
            tempArr.push({ code: item.key, label: item.label || item.value, dataType: 'String', value: item.code });
          }
        });
        arr = value.length !== 0 ? JSON.stringify(tempArr) : null;
      }
      form.customizedPlaceholder = arr;
      //   form.filterChar = this.form.filterChar.join(',');
      if (this.form.type !== 'CODE' && form.startSequenceNo.length !== form.endSequenceNo.length) {
        this.$message.error('起始流水号和结束流水号位数不相等');
        loading();
        return;
      }
      add(form).then(
        () => {
          this.onLoad(this.page);
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          done();
        },
        (error) => {
          loading();
          window.console.log(error);
        }
      );
    },
    rowUpdate(form, index, done, loading) {
      form['sequenceNoFormat'] = this.form.sequencenoformat;
      let arr;
      if (this.form.type === 'CODE') {
        let tempArr = [];
        value.forEach((item) => {
          if (this.form.sequencenoformat.includes(item.key)) {
            tempArr.push({ code: item.key, label: item.label || item.value, dataType: 'String', value: item.customValue });
          }
        });
        arr = value.length !== 0 ? JSON.stringify(tempArr) : null;
      } else {
        const value = this.seqNoRulesList[2].value || [];
        let tempArr = [];
        value.forEach((item) => {
          if (this.form.sequencenoformat.includes(item.key)) {
            tempArr.push({ code: item.key, label: item.label || item.value, dataType: 'String', value: item.customValue });
          }
        });
        arr = value.length !== 0 ? JSON.stringify(tempArr) : null;
      }
      //提交的参数中值为undefined的字段会被过滤，防止清空的数字类型不能传给后端改变其值将undefined转为null
      Object.keys(form).forEach((item) => {
        const key = form[item];
        if (key === undefined) {
          form[item] = null;
        }
      });
      form.customizedPlaceholder = arr;
      //  form.filterChar = this.form.filterChar.join(',');
      if (this.form.type !== 'CODE' && form.startSequenceNo.length !== form.endSequenceNo.length) {
        this.$message.error('起始流水号和结束流水号位数不相等');
        loading();
        return;
      }
      update(form).then(
        () => {
          this.onLoad(this.page);
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          done();
        },
        (error) => {
          loading();
          console.log(error);
        }
      );
    },
    rowDel(row) {
      this.$confirm('确定将选择数据删除?', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          return remove(row.id);
        })
        .then(() => {
          this.onLoad(this.page);
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
        });
    },
    handleDelete() {
      if (this.selectionList.length === 0) {
        this.$message.warning('请选择至少一条数据');
        return;
      }
      this.$confirm('确定将选择数据删除?', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          return remove(this.ids);
        })
        .then(() => {
          this.onLoad(this.page);
          this.$message({
            type: 'success',
            message: '操作成功!'
          });
          this.$refs.crud.toggleSelection();
        });
    },
    async beforeOpen(done, type) {
      this.seqNoRulesList[2].value = [];

      if (this.columns.length > 0) {
        this.option.column = this._cloneDeep(this.columns);
      } else {
        this.columns = this._cloneDeep(this.option.column);
      }
      if (['add'].includes(type)) {
        // this.form.hexString = '0123456789';
        this.form.incrementQty = 1;
        const column = this.findObject(this.option.column, 'baseType');
        column.disabled = false;
        this.form.hexString = this.customHexString;
      }
      if (['edit', 'view'].includes(type)) {
        if (type === 'view') this.inputDisabled = true;
        await getDetail(this.form.id).then((res) => {
          this.form = res.data.data;
          //    this.form.filterChar = (res.data.data.filterChar && res.data.data.filterChar.split(',')) || [];
          this.customHexString = this.form.hexString;
          const customizedPlaceholderArr = this._cloneDeep(res.data.data.customizedPlaceholder);
          const customizedPlaceholder = JSON.parse(customizedPlaceholderArr);
          if (customizedPlaceholder) {
            const value = customizedPlaceholder.map((item) => {
              return {
                code: item.code,
                value: item.label,
                key: item.code,
                customValue: item.value || ''
              };
            });
            this.$set(this.seqNoRulesList[2], 'value', value);
          }

          let reg = /^[0-9]\d*$/g;
          let str = /^[A-F0-9]+$/;
          if (reg.test(this.form.hexString)) {
            this.form.baseType = 10;
          } else if (str.test(this.form.hexString)) {
            this.form.baseType = 16;
          } else {
            this.form.baseType = 'custom';
          }
          const column = this.findObject(this.option.column, 'baseType');
          column.disabled = true;

          //将值为null的字段值转为undefined，防止被数字类型的输入框将null转为1
          Object.keys(this.form).forEach((item) => {
            const key = this.form[item];
            if (key === null) {
              this.form[item] = undefined;
            }
          });
          // this.viewEditBarCode();
        });
        this.isFieldShow(this.form.type);
      }
      const seqNoRulesKey = [];
      this.seqNoRulesList.forEach((item) => {
        if (item.value) {
          item.value.forEach((el) => {
            seqNoRulesKey.push(el.key);
          });
        }
      });
      this.seqNoRulesKey = seqNoRulesKey;
      done();
    },
    handleEditCustomField(val, index) {
      const { code = '', key = '', value = '', dataType = 'string', label = '', customValue } = this._cloneDeep(val);
      this.currentIndex = index;
      this.currentKey = key;
      this.customForm = {
        label: value,
        code: key,
        value: customValue
      };
    },
    handleSetCustomField(val, index) {
      if (this.isSubmit) {
        const { label, code, value } = this.customForm;
        const item = { key: code, value: label, dataType: 'string', code: value, label, customValue: value };
        this.$set(this.seqNoRulesList[2].value, index, item);
        this.seqNoRulesKey.push(code);
        this.customForm = {};
        // this.isSubmit = false;
        return;
      }
      this.$message.error('自定义字符配置错误，请检查');
    },
    handleDeleteField(val, index) {
      const field = this._cloneDeep(this.seqNoRulesList[2].value);
      field.splice(index, 1);
      this.$set(this.seqNoRulesList[2], 'value', field);
    },

    /*
     * 查看编辑类型为条形码识别时
     */
    viewEditBarCode() {
      if (this.form.type === 'CODE') {
        //根据规则[N1][N2][N3]添加对用的规则和input
        let reg = /N[(\d+)]/g; //正则匹配[N1] => N1
        let res = this.form.sequenceNoFormat.match(reg);
        this.customizedPlaceholder = JSON.parse(this.form.customizedPlaceholder);
        //添加自定义字符
        this.seqNoRulesList[2].value = this._map(JSON.parse(this.form.customizedPlaceholder), (item, idx) => {
          if (item.label) {
            this.form[item.code] = item.label;
          }
          return {
            code: '',
            key: `[${item.code}]`,
            value: item.label,
            class: ''
          };
        });
        //添加自定义字符对应的input
        // this._forEach(res, (item, idx) => {
        //   let flag = this.option.column.every((item2) => {
        //     return item2.prop !== item;
        //   });
        //   if (flag) {
        //     this.option.column = [
        //       ...this.option.column,
        //       {
        //         label: `自定义字符${item.substr(1, item.length)}`,
        //         prop: `${item}`,
        //         hide: true,
        //         rules: [
        //           {
        //             required: true,
        //             message: `请输入自定义字符${item.substr(1, item.length)}`,
        //             trigger: 'blur'
        //           }
        //         ]
        //       }
        //     ];
        //   }
        // });
        this.$nextTick(() => {
          this.option.column = this._map(this.option.column, (item) => {
            switch (item.prop) {
              case 'type':
                item.disabled = false;
                return item;
              case 'name':
                item.disabled = false;
                return item;
              case 'code':
                item.disabled = false;
                return item;
              case 'sequencenoformat':
                item.disabled = false;
                return item;
              default:
                if (!item.label.includes('自定义字符')) {
                  item.disabled = true;
                }
                return item;
            }
          });
        });
      }
    },
    beforeClose(done) {
      this.form = new Object();
      this.inputDisabled = false;
      // this.$nextTick(() => { //打开模态框之前获取表单元素
      //     // this.$refs.crud.resetForm(); //Avue清空方法
      //     this.$refs['crud'].clearValidate();
      // })
      this.selectedRuleCodes = new Object();
      // this.$set(this.selectedRuleCodes, {});
      this.isCollapsed = false;
      done();
    },
    searchReset() {
      this.query = {};
      this.onLoad(this.page);
    },
    searchChange(params, done) {
      this.query = params;
      this.page.currentPage = 1;
      this.onLoad(this.page, params);
      done();
    },
    selectionChange(list) {
      this.selectionList = list;
    },
    selectionClear() {
      this.selectionList = [];
      this.$refs.crud.toggleSelection();
    },
    currentChange(currentPage) {
      this.page.currentPage = currentPage;
    },
    sizeChange(pageSize) {
      this.page.pageSize = pageSize;
    },
    refreshChange() {
      this.onLoad(this.page, this.query);
    },
    onLoad(page, params = {}) {
      this.loading = true;
      getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then((res) => {
        const data = res.data.data;
        this.page.total = data.total;
        this.data = data.records;
        this.data.forEach((ele) => {
          ele.sequencenoformat = ele.sequenceNoFormat;
        });
        this.loading = false;
        this.selectionClear();
      });
    },
    /*
     * 添加自动义字符
     */
    addCustomCode() {
      let len = this.seqNoRulesList[2].value.length || 0;
      this.seqNoRulesList[2].value.push({
        code: '',
        key: `[N${len + 1}]`,
        value: `自定义字符${len + 1}`,
        label: `自定义字符${len + 1}`,
        class: '',
        customValue: '',
        dataType: 'string'
      });
      this.customizedPlaceholderFn();
    },
    isFieldShow(val) {
      if (this.form.isPregenerated) {
        return;
      }
      const setDisabled = (item) => {
        if (item.prop != 'serialNumberTotal') {
          switch (item.prop) {
            case 'hexString':
              item.disabled = true;
              break;
            case 'serialNumberTotal':
              item.disabled = true;
              break;
            default:
              item.disabled = false;
              break;
          }
        }
      };
      const column = this._cloneDeep(this.option.column);
      if (!val) {
        column.forEach((item) => {
          item.display = true;
          item.viewDisplay = true;
          item.editDisplay = true;
          if (item.isCustomChart) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          setDisabled(item);
        });
      } else if (val === 'CODE') {
        column.forEach((item) => {
          if (['baseInfo', 'rulesCofig', 'type', 'name', 'code', 'sequencenoformat', 'sequenceSample', 'preview'].includes(item.prop)) {
            item.display = true;
            item.viewDisplay = true;
            item.editDisplay = true;
          } else {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          switch (item.prop) {
            case 'type':
              item.disabled = false;
              return item;
            case 'name':
              item.disabled = false;
              return item;
            case 'code':
              item.disabled = false;
              return item;
            case 'sequencenoformat':
              item.disabled = false;
              return item;
            default:
              if (item.label && !item.label.includes('自定义字符')) {
                item.disabled = true;
              }
              return item;
          }
          // this.option.column = this._forEach(this.option.column, (item) => {});
        });
      } else if (val === 'OUTSN') {
        column.forEach((item) => {
          if (
            [
              'baseInfo',
              'rulesCofig',
              'sequenceSample',
              'delimiter',
              'prefix',
              'suffix',
              'startSequenceNo',
              'endSequenceNo',
              'sequencenoformat',
              'type',
              'name',
              'code',
              'charactersCount',
              'identificationCode',
              'groupingRule'
            ].includes(item.prop)
          ) {
            item.display = true;
            item.viewDisplay = true;
            item.editDisplay = true;
          } else {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = true;
          }
          if (item.isCustomChart) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          setDisabled(item);
        });
      } else if (val === 'SN') {
        column.forEach((item) => {
          if (!['groupingRule', 'charactersCount', 'identificationCode'].includes(item.prop)) {
            item.display = true;
            item.viewDisplay = true;
            item.editDisplay = true;
          } else {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          if (item.isCustomChart) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          setDisabled(item);
        });
      } else {
        column.forEach((item) => {
          if (['groupingRule', 'charactersCount', 'identificationCode', 'serialNumberTotal'].includes(item.prop)) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          } else {
            item.display = true;
            item.viewDisplay = true;
            item.editDisplay = true;
          }
          if (item.isCustomChart) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
          }
          setDisabled(item);
        });
      }
      if (!this.form.isPregenerated) {
        column.forEach((item) => {
          if (['used', 'total'].includes(item.prop)) {
            item.display = false;
            item.viewDisplay = false;
            item.editDisplay = false;
            setDisabled(item);
          }
        });
      }
      this.$set(this.option, 'column', column);
    }
  }
};
</script>

<style lang="scss" scoped>
::v-deep .sequence-dropdown {
  position: relative;
  top: 0px;
  left: 0px;
  z-index: 9999999;
  display: none;
  width: 490px;
  height: 306px;
  min-width: 10rem;
  /* padding-left: 10px;
  padding-right: 10px; */
  font-size: 14px;
  text-align: left;
  background-color: #fff;
  border: 1px solid #ccc;
  border-radius: 3px;
  box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3);
}
.form-title {
  padding-left: 5px;
  font-weight: 700;
  margin-bottom: 0;
  margin-top: 5px;
  border-bottom: 1px dashed #ccc;
  border-left: 4px solid #4285a5;
  line-height: 22px;
}
#sequenceDropdown.show {
  display: block;
  /* overflow: scroll; */
}
.sequence-dropdown .checkbox label {
  /*margin-right: 12px;*/
}
.el-icon-circle-close {
  /* position: absolute; */
  right: 3px;
  font-size: 23px;
  top: 2px;
  cursor: pointer;
}
.closeDropDown {
  text-align: right;
  border-bottom: 1px solid #cccccc;
  height: 30px;
  padding-top: 3px;
  padding-right: 3px;
}
.seqNoRulesList {
  padding: 0 10px;
  height: 88%;
  overflow-y: auto;
  overflow-x: hidden;
}
.custom-check-box {
  margin-left: 8px;
}
.title {
  height: 35px;
  display: flex;
  text-align: center;
  align-items: center;
  position: relative;
  left: -160px;
}
.custom-char {
  display: flex;
  width: 50%;
  margin-right: 12px;
  .btn-del {
    margin-left: 12px;
  }
}
::v-deep .el-row.customCode {
  display: flex !important;
  flex-direction: column !important;
}
.custom-form {
  display: flex;
  flex-direction: column;
  align-items: center;
  .btn-save {
    width: 80px;
    position: relative;
    top: -23px;
    left: 20px;
  }
}
</style>
